<?php
// +----------------------------------------------------------------------
// | Yzncms [ 御宅男工作室 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2018 http://yzncms.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 御宅男 <530765310@qq.com>
// +----------------------------------------------------------------------

// +----------------------------------------------------------------------
// | 用户自定义函数库
// +----------------------------------------------------------------------
use EasyWeChat\Factory;
use think\Db;
use think\Image;
use think\facade\Session;


use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest;
use AlibabaCloud\Tea\Exception\TeaError;
use AlibabaCloud\Tea\Utils\Utils;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
//use App\Lib\Config\SmsKeyConstant;
use Darabonba\OpenApi\Models\Config;
//use Exception;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;

function sendAliyunSms($phone, $signName, $templateCode, $templateParam) {
    // 初始化客户端
    AlibabaCloud::accessKeyClient(
        'LTAI5tQ79ZzCBiyFGKZiAFdv',      // 替换为你的AccessKey ID
        'B9k5lUrPhX68IFaBUqSrt70r08HEMz'   // 替换为AccessKey Secret
    )->regionId('cn-hangzhou')     // 默认杭州区域
    ->asDefaultClient();

    try {
        $result = AlibabaCloud::rpc()
            ->product('Dysmsapi')
            ->version('2017-05-25')
            ->action('SendSms')
            ->method('POST')
            ->host('dysmsapi.aliyuncs.com')
            ->options([
                'query' => [
                    'PhoneNumbers'  => $phone,
                    'SignName'      => $signName,
                    'TemplateCode'  => $templateCode,
                    'TemplateParam' => json_encode($templateParam),
                ],
            ])
            ->request();
        return $result->toArray();
    } catch (ClientException $e) {
        return ['error' => $e->getErrorMessage()];
    } catch (ServerException $e) {
        return ['error' => $e->getErrorMessage()];
    }
}
 function template2($code){
    $data=sendAliyunSms( '8617602555019',          // 手机号（注意去掉+号）
        '山东省鉴证技术咨询',                 // 短信签名
        'SMS_315985013',         // 模板CODE
        ['code' => $code] );// 模板参数);
    msg(0, "获取成功", $data);
}


function template_2($phoneNumbers, $name, $code, $address, $content)
{
    //1.使用AK&SK初始化账号Client对象
    $config = new Config([
        // 必填，您的 AccessKey ID
        "accessKeyId" => config('aliyun.ACCESS_KEY_ID'),
        // 必填，您的 AccessKey Secret
        "accessKeySecret" => config('aliyun.ACCESS_KEY_SECRET'),
    ]);
    // 访问阿里云的域名SSS
    $config->endpoint =config('aliyun.END_POINT');
    $client = new Dysmsapi($config);
    //2.发送短信息的模板、验证码、签名、手机号准备
    $templateParam = json_encode([  'code' => $code]);#code键名与短信模板中的${code}一致
//    $templateParam = json_encode(['name' => $name, 'code' => $code, 'address' => $address, 'content' => $content]);#code键名与短信模板中的${code}一致
    $sendSmsRequest = new SendSmsRequest([
        "phoneNumbers" => $phoneNumbers,
        "signName" => config('aliyun.SIGN_NAME'),
        "templateCode" => config('aliyun.TEMPLATE_CODE_2'),
        "templateParam" => $templateParam
    ]);
    //3.准备发送
    $runtime = new RuntimeOptions([]);
    try {
        // 复制代码运行请自行打印 API 的返回值
        $data = $client->sendSmsWithOptions($sendSmsRequest, $runtime);
        print_r($data);
//            var_dump("---------------------------------------------------");
        return $data;
    } catch (Exception $error) {
        if (!($error instanceof TeaError)) {
            $error = new TeaError([], $error->getMessage(), $error->getCode(), $error);
//                var_dump($error);
        }
        // 如有需要，请打印 error
//            var_dump(Utils::assertAsString($error->message));
        return Utils::assertAsString($error->message);
    }
}



function conf($val = "", $vals = "")
{
    return config()[$val][$vals];
}

function responseJson($code = 0, $msg = '', $data = null)
{
    $response = array(
        'code' => $code,
        'data' => $data,
        'msg' => $msg
    );
    exit(json_encode($response));
}

function lmcurl($url)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FAILONERROR, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    $SSL = substr($url, 0, 8) == "https://" ? true : false;
    if ($SSL) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 检查证书中是否设置域名
    }
    $content = curl_exec($ch);
    curl_close($ch);
    return $content;
}

function msg($code = 0, $msg = "", $data, $count = 1)
{

    $res['code'] = $code;

    $res['msg'] = $msg;

    $res['data'] = $data;

    $res['count'] = $count;

    exit(arj($res));

}

function arj($data, $isformdata = 1)
{
    if ($data == '' || empty($data)) return '';

    // if($isformdata) $data = new_stripslashes($data);

    if (version_compare(PHP_VERSION, '5.3.0', '<')) {
        return json_encode($data, JSON_UNESCAPED_UNICODE);
    } else {
        return json_encode($data, JSON_UNESCAPED_UNICODE);
    }
}

/**
 * 获取微信小程序token
 * @return bool|string
 */
function getAccessToken()
{
    $appid = config('wechat.appID');
    $secret = config('wechat.AppSecret');
    $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $secret;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);

    curl_setopt($ch, CURLOPT_HEADER, 0);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    $res = curl_exec($ch);
    curl_close($ch);
    return $res;
}

function getDistance($from, $to)
{
//
    $lastPos = strrpos($to, ';');
    if ($lastPos !== false) {
        $to = explode(';', $to)[1];
    }
//
    $to = explode(',', $to);

    $from = explode(',', $from);

    $radLat1 = deg2rad(floatval($to[1]));// deg2rad()函数将角度转换为弧度

    $radLat2 = deg2rad(floatval($from[1]));

    $radLng1 = deg2rad(floatval($to[0]));

    $radLng2 = deg2rad(floatval($from[0]));

    $a = $radLat1 - $radLat2;

    $b = $radLng1 - $radLng2;

    $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137;

    return round($s, 2);
}

//通过IP获取地址
function getDistrictByIP($ip)
{
    $url = "http://ip-api.com/json/" . $ip;
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);

    $data = json_decode($response, true);
    if ($data && $data['status'] === 'success') {
        return $data['city']; // 返回区县名
    } else {
        return 'Unknown';
    }
}

//获取订单号
function GetOrderSN($type, $data = array())
{

    if ($type == 1) {


        $city_code = cityCode($data);

        $time = date('ymd');

        $lennum = lennum();

        $ordersn = $time . $city_code . $lennum;

        return $ordersn;
    }

    if ($type == 2) {
        $order_id_main = date('YmdHis') . rand(100000, 999999);
        $order_id_len = strlen($order_id_main);
        $order_id_sum = 0;
        for ($i = 0; $i < $order_id_len; $i++) {
            $order_id_sum += (int)(substr($order_id_main, $i, 1));
        }
        $osn = $order_id_main . str_pad((100 - $order_id_sum % 100) % 100, 2, '0', STR_PAD_LEFT);
        return $osn;
    }

}

/**
 * 区号
 */

function cityCode($data)
{
    $los = $data['lat'] . ',' . $data['lng'];

    $url = "https://apis.map.qq.com/ws/geocoder/v1/?location=" . $los . "&key=" . config('MapKey') . "&type=json";

    $res = lmcurl($url);

    $city = string2array($res);


    if ($city['status'] != 0) {

        GetOrderSN(1, $data);

    }
    $ad_info = $city['result']['ad_info'];

    $length = strlen($ad_info['phone_area_code']);

    $city_code = $ad_info['phone_area_code'];

    if ($length > 3) {
        $city_code = substr($city_code, 1, 3);
    }

    return $city_code;
}

/**
 * 根据地址返回坐标
 */
function getLWByAddress($address)
{
    $key = config('wechat.geocodeMap_1');
    $url = 'https://restapi.amap.com/v3/geocode/geo?key=' . $key . '&address=' . urlencode($address);
    $response = file_get_contents($url);
    $jsonResponse = json_decode($response, true);
    if ($jsonResponse['status'] == '1') {
        $jsonResponse['geocodes'][0]['location'] = explode(',', $jsonResponse['geocodes'][0]['location']);
        return json_encode(array(
            'code' => 0,
            'data' => $jsonResponse['geocodes'][0]['location']
        ));
    } else {
        return json_encode(array(
            'code' => -1,
            'data' => $jsonResponse
        ));
    }
}

/**
 * 获取前天时间戳范围默认昨天
 */
function getTimestamp($day = -1)
{
    $data_string = $day . " day";
    $yesterday = date("Y-m-d", strtotime($data_string));

// 昨天开始时间戳
    $yesterdayStartTimestamp = strtotime($yesterday . " 00:00:00");

// 昨天结束时间戳
    $yesterdayEndTimestamp = strtotime($yesterday . " 23:59:59");

    return array(
        0 => $yesterdayStartTimestamp,
        1 => $yesterdayEndTimestamp
    );
}

function objectToArray($object)
{
    $jsonString = json_encode($object);
    $array = json_decode($jsonString, true);

    return $array;
}

//生成小程序二维码
function qrcode($value, $page, $width = 600)
{
    try {
        $config = [
            'app_id' => config('wechat.appID'),
            'secret' => config('wechat.AppSecret'),
        ];
        $app = Factory::miniProgram($config);
        $response = $app->app_code->getUnlimit($value, [
            'page' => $page,
            'width' => $width,
        ]);
        if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
            $filename = $response->save(ROOT_PATH . 'public/uploads/drivingcode', 'qrcode' . time());
            return config('wechat.url') . '/uploads/drivingcode/' . $filename;
        }
//        msg(-1, '', $response);
        return $response;
    } catch (\Exception $e) {
//        msg(-1, $e->getMessage(), '');
        return $e->getMessage();
    }
}

function showMsg($status, $message = '', $data = array())
{
    $result = array(
        'status' => $status,
        'message' => $message,
        'data' => $data
    );
    exit(json_encode($result));
}

function formatSizeUnits($bytes)
{
    if ($bytes >= 1073741824) {
        // 大于等于 1 GB
        $bytes = number_format($bytes / 1073741824, 2) . ' GB';
    } elseif ($bytes >= 1048576) {
        // 大于等于 1 MB
        $bytes = number_format($bytes / 1048576, 2) . ' MB';
    } elseif ($bytes >= 1024) {
        // 大于等于 1 KB
        $bytes = number_format($bytes / 1024, 2) . ' KB';
    } else {
        // 小于 1 KB
        $bytes = $bytes . ' Bytes';
    }
    return $bytes;
}

//1看视频 2兑换 3其他
function addFraction($memberId, $fraction_count = 2, $desc = ' ', $type = 1, $is_count = 1)
{
    $insert_data = array(
        'member_id' => $memberId,
        'create_time' => time(),
        'count' => $fraction_count,
        'desc' => $desc,
        'type' => $type,
        'is_count' => $is_count,
    );
    Db::name('fraction_record')->insertGetId($insert_data);
    if ($is_count == 1) {
        Db::name('member')
            ->where('id', '=', $memberId)
            ->setInc('fraction', $fraction_count);
    } else {
        Db::name('member')
            ->where('id', '=', $memberId)
            ->setDec('fraction', $fraction_count);
    }
}

//获取优惠券
function getCoupons($memberId, $coupon_info, $get_type = 1, $invite_member_id = 0)
{
    $now_time = time();
    $insert_data = array(
        'member_id' => $memberId,
        'coupon_id' => $coupon_info['id'],
        'name' => $coupon_info['name'],
        'value' => $coupon_info['value'],
        'min_amount' => $coupon_info['min_amount'],
        'claimed_time' => $now_time,
        'start_time' => $now_time,
        'create_time' => time(),
        'get_type' => $get_type,
        'invite_member_id' => $invite_member_id,
        'desc' => $coupon_info['desc']
    );
    if ($coupon_info['effect_type'] == 1) {
        $insert_data['end_time'] = $coupon_info['effect_end'];
    } else {
        $insert_data['end_time'] = $now_time + ($coupon_info['effect_day'] * 86400);
    }
    //领取张数
    Db::name('coupons')
        ->where('id', '=', $coupon_info['id'])
        ->setInc('claimed_count');
    //增加会员优惠券
    $result_id = Db::name('member_coupons')->insertGetId($insert_data);
    return $result_id;
}

//订单回调
function orderPaySuccess($order_data)
{
    $order_update = array(
        'id' => $order_data['id'],
        'status' => 2,
        'pay_time' => time(),
        'pay_status' => 1,
    );
    Db::startTrans();
    try {
        Db::name('order')->update($order_update);
        if ($order_data['mc_id']) {
            $mc_update = array(
                'id' => $order_data['mc_id'],
                'status' => 3,
            );
            Db::name('member_coupons')->update($mc_update);
        }
        Db::commit();
        return 1;
    } catch (\Exception $e) {
        Db::rollback();
        return -1;
    }
}

function finishOrder($order_info, $type = 1)
{
    $update_data = array(
        'id' => $order_info['id'],
        'status' => 4,
        'finish_time' => time(),
        'finish_type' => $type
    );
    Db::name('order')->update($update_data);
}

//1待支付 2待发货 3待收货 4已完成 5已评价 6售后退货
//7已取消
function tuikuanServerOrder($order_info, $tui_moeny = 0.00, $is_houtui = 0)
{
    $update_data = array(
        'id' => $order_info['id'],
        'status' => 6,
        'is_tui' => 1,
        'pay_status' => 2,
        'tui_time' => time(),
        'is_houtui' => $is_houtui,
        'tui_moeny' => $tui_moeny
    );
    //优惠券
    if ($order_info['mc_id']) {
        Db::name('member_coupons')->update([
            'id' => $order_info['mc_id'],
            'status' => 1,
        ]);
    }
    //订单信息  order_after status 1待同意 2已同意 3已拒绝 4已发货 5已完成
    Db::name('order')->update($update_data);
    if ($is_houtui == 1) {
        $order_after = array(
            'tui_no' => 'cp' . GetOrderSN(2),
            'order_no' => $order_info['order_no'],
            'order_id' => $order_info['id'],
            'status' => 5,
            'create_time' => time(),
            'tui_reason' => '后台主动退款',
            'order_pay_money' => $order_info['pay_money'],
            'member_id' => $order_info['member_id'],
            'is_fa' => 0,
            'order_status' => 6,
            'tui_money' => $tui_moeny,
        );
        Db::name('order_after')->insertGetId($order_after);
    }
}

//发送消息
function sendMsg($message_cate_id, $title, $content, $member_id)
{
    $insert_data = array(
        'message_cate_id' => $message_cate_id,
        'title' => $title,
        'content' => $content,
        'create_time' => time(),
        'member_id' => $member_id
    );
    Db::name('message')->insertGetId($insert_data);
}

//发送验证码
function sendVerifyCode($phone)
{
    $code = rand(1000, 9999); // 6位随机验证码
//    Session::set('verify_code'.$phone, $code); // 5分钟过期
    $insert_data = array(
        'name' => $phone,
        'code' => $code,
        'create_time' => time(),
        'effect_time' => time() + 60 * 5,
    );
    $id = Db::name('verify_code')->insertGetId($insert_data);
    Db::name('verify_code')->where([
        ['id', '<>', $id],
        ['name', '=', $phone],
    ])->update([
        'is_del' => 1
    ]);
    sendAliyunSms( '86'.$phone,          // 手机号（注意去掉+号）
        '山东省鉴证技术',                 // 短信签名
        'SMS_483315329',         // 模板CODE
        ['code' => $code] );
    return $code;
    // $response = sendSmsCode('13800138000', $code);
}

//检测验证码
function checkCode($phone, $code)
{
    //删除超过5分钟的验证码
    Db::name('verify_code')->where([
        ['name', '=', $phone],
        ['effect_time', '<', time()],
    ])->update([
        'is_del' => 1
    ]);
    $verify_code=Db::name('verify_code')->where([
        ['name', '=', $phone],
        ['is_del', '=', 0],
    ])->order('create_time desc')->find();
    if ($verify_code['code']!=$code){
        return 0;
    }
//    if (Session::get('verify_code' . $phone) != $code) {
//        return 0;
//    }

    // 验证通过后清除Session
    Db::name('verify_code')->where([['name', '=', $phone],])
        ->update([
            'is_del' => 1
        ]);
//    Session::delete('verify_code'.$phone);
    return 1;
}

//生成token
function generateToken($phone)
{
    // 组合：手机号 + 设备指纹 + 随机字符串
    $deviceFingerprint = $_SERVER['HTTP_USER_AGENT'] ?? 'default';
    $randomStr = bin2hex(random_bytes(8));
    $rawToken = $phone . '|' . $deviceFingerprint . '|' . $randomStr;

    // 加密存储（建议使用hash_hmac）
    return hash_hmac('sha256', $rawToken, 'your_secret_key');
}

//查询使用数量
function useQueryNum($member_id)
{
    $member_account = Db::name('member_account')->where([
        ['count', '>', 0],
        ['effect_data', '>=', time()],
        ['member_id', '=', $member_id],
    ])->order('effect_data')->find();
    if (!$member_account) {
        return -1;
    }
    Db::name('member_account')
        ->where('id', '=', $member_account['id'])
        ->update([
            'count' => Db::raw('count-1'), // 库存减1
            'use_count' => Db::raw('use_count+1')  // 销量加1
        ]);
    return 0;
}

//单条数据转树状数据
function listToTree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0)
{
    $tree = array();// 创建Tree
    if (is_array($list)) {
        // 创建基于主键的数组引用
        $refer = array();
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] =& $list[$key];
        }

        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[$data[$pk]] =& $list[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent =& $refer[$parentId];
                    $parent[$child][] =& $list[$key];
                }
            }
        }
    }
    return $tree;
}

//增加余额
function addMoney($member_id, $num, $is_count, $order_id, $type = 1)
{
    //1充值 2物价消耗 3汽配消耗 4专家消耗 5评估消耗
    switch ($type) {
        case 1:
            $desc = '充值';
            break;
        case 2:
            $desc = '物价消耗';
            break;
        case 3:
            $desc = '汽配消耗';
            break;
        case 4:
            $desc = '专家消耗';
            break;
        case 5:
            $desc = '评估消耗';
            break;
        default:
            $desc = '物价消耗';
    }
    $insert_data = array(
        'member_id' => $member_id,
        'money' => $num,
        'order_id' => $order_id,
        'is_count' => $is_count,
        'type' => $type,
        'desc' => $desc,
        'create_time' => time()
    );
    if ($is_count == 1) {
        Db::name('member')->where(['id' => $member_id])->setInc('money', $num);
    } else {
        Db::name('member')->where(['id' => $member_id])->setDec('money', $num);
    }
    $insert_id = Db::name('money_record')->insertGetId($insert_data);
    return $insert_id;
}








